import type { App } from "vue";
import type {
  RightMenuProps,
  RightMenuItem,
} from "@/components/cl-context-menu";
import RightMenuComponent from "@/components/cl-context-menu/index.vue";

// 挂载后的DOM节点
let menuVM: HTMLDivElement | null = null;

/**
 * 将组件挂载到节点上
 * @param comp 需要挂载的组件
 * @param prop 向组件传的参数
 */
const createComp = (comp: Component, prop: RightMenuProps) => {
  const app = createApp(comp, prop as any);
  const div = document.createElement("div");
  document.body.appendChild(div);
  //将组件挂载到节点上
  app.mount(div);
  return div;
};

function onContextMenu(
  el: HTMLElement,
  binding: globalThis.DirectiveBinding<any, string, string>,
  e: MouseEvent
) {
  // 阻止浏览器右键菜单
  e.preventDefault();

  if (menuVM) {
    // 销毁上次触发的右键菜单
    document.body.removeChild(menuVM);
    menuVM = null;
  }

  //收集所有的文本和对应的处理函数
  const textArray = binding.value.map((item: RightMenuItem) => item.text);
  const handlerArray = binding.value.map((item: RightMenuItem) => item.handler);
  if (!textArray || !handlerArray) {
    throw new Error("右键菜单内容与事件处理函数为必传项");
  }
  if (textArray.length !== handlerArray.length) {
    throw new Error("每个右键菜单项都要有对应的事件处理函数");
  }
  const menuList = binding.value.map((item: RightMenuItem, index: number) => ({
    ...item,
    id: index + 1,
  }));

  menuVM = createComp(RightMenuComponent, {
    rightMenuStatus: "block",
    rightMenuTop: e.clientY + "px",
    rightMenuLeft: e.clientX + "px",
    rightMenuList: menuList,
    rightClickEvent: e,
  });
}

export default {
  install(app: App): void {
    app.directive("rightClick", (el, binding) => {
      function handleContextMenu(e: MouseEvent) {
        onContextMenu(el, binding, e);
      }
      el.removeEventListener("contextmenu", handleContextMenu);
      el.addEventListener("contextmenu", handleContextMenu);
    });

    document.body.addEventListener("click", () => {
      if (menuVM) {
        // 销毁右键菜单DOM
        document.body.removeChild(menuVM);
        menuVM = null;
      }
    });
  },
};
